package util.instance;

import objects.base.Collidable;

import org.newdawn.slick.Game;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.state.StateBasedGame;

import util.level.Room;
import util.resource.Sprite;

/**
 * Superclass for all game objects which have a position.
 * @author Logan
 */
public abstract class Instance
{
	protected Sprite sprite = null;
	public float x=0;
	public float y=0;
	protected boolean isDestroyed=false;
	protected byte depth;
	
	/**
	 * Constructor for the instance. Doesn't really do anything atm.
	 */
	public Instance()
	{
	}
	
	/**
	 * Rendering occurs just after the step event. Try to keep out all movement logic
	 * and only include rendering logic in this method. By default, it simply draws the
	 * current sprite if it exists.
	 * @param gc - the current game container.
	 * @param game - the current game.
	 * @param g - the current graphics.
	 */
	public void render(GameContainer gc,Game game,Graphics g)
	{
		if(sprite!=null)
			sprite.render(x,y,gc,game,g);
	}
	
	/**
	 * The step event, which is the first event to be called in the game loop. This should
	 * handle all the movement and input and it should include absolutely no rendering.
	 * @param gc - the current game container.
	 * @param game - the current game.
	 */
	public void step(GameContainer gc,StateBasedGame game,Room room)
	{
		if(sprite!=null)
			sprite.update(gc,game);
	}
	
	/**
	 * Called after the rendering has completed. This is a good place to put collision logic, though
	 * it also can be in the step event if it depends on the motion of the object.
	 * @param gc - the current game container.
	 * @param game - the current game.
	 */
	public void endStep(GameContainer gc,Game game,Room room)
	{
		
	}
	
	/**
	 * Called automatically at the end of the game loop after the object is destroyed. This
	 * is the last event to be called in the game loop.
	 * @param gc - the current game container.
	 * @param sbg - the current game.
	 * @param room - the current room.
	 */
	public void destroy(GameContainer gc,StateBasedGame sbg,Room room)
	{
		
	}
	
	/**
	 * Called when the instance is added to the instanceList.
	 * @param gc - the current game container.
	 * @param sbg - the current game.
	 * @param room - the current room.
	 */
	public void creation(GameContainer gc,StateBasedGame sbg,Room room)
	{
		
	}
	
	/**
	 * Call this to signal to the object manager to remove this object at
	 * the end of the current game loop.
	 */
	public void instanceDestroy()
	{
		isDestroyed=true;
	}
	
	/**
	 * You want to handle collision in a separate method? We've got a method for that. Not really required
	 * but helpful in many situations.
	 * @param otherObj - instance that we have collided with.
	 */
	protected void collision(Room room,Collidable otherObj)
	{
		
	}
	
	//Getters and setters below
	/**
	 * Returns the x position of the object.
	 * @return the x position of the object
	 */
	public float getX(){return x;}
	/**
	 * Returns the y position of the object.
	 * @return the y position of the object
	 */
	public float getY(){return y;}
	/**
	 * Returns the current sprite of the object. This may be different than what is
	 * being displayed if the render method is overwritten.
	 * @return the sprite of this object
	 */
	public Sprite getSprite(){return sprite;}
	/**
	 * Sets the x position of this instance.
	 * @param x - the x position
	 */
	public void setX(int x){this.x=x;}
	/**
	 * Sets the y position of this instance.
	 * @param y - the y position
	 */
	public void setY(int y){this.y=y;}
}
